﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace CatEars.Core.Net
{
    /// <summary>
    /// Http请求扩展
    /// </summary>
    public static class HttpRequestEx
    {
          /// <summary>
        /// 默认 User-agentHTTP 标头的值。
        /// </summary>
        public static string DefaultUserAgent { get; set; }

        /// <summary>
        /// Http请求类
        /// </summary>
        static HttpRequestEx()
        {
            DefaultUserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0";
            if (System.Net.ServicePointManager.DefaultConnectionLimit < 500)
            {
                System.Net.ServicePointManager.DefaultConnectionLimit = 500;
            }
        }

        /// <summary>
        /// 创建HttpRequest
        /// </summary>
        /// <param name="strUrl">Url</param>
        /// <param name="strMethod">Get or Post</param>
        /// <param name="intTimeoutMs">超时时间 毫秒</param>
        /// <param name="strReferer">referer</param>
        /// <param name="cookies">cookies</param>
        /// <param name="headers">headers</param>
        /// <returns>HttpRequest对象</returns>
        public static HttpWebRequest CreateHttpRequest(
            string strUrl,
            string strMethod,
            int? intTimeoutMs = null,
            string strReferer = null,
            CookieCollection cookies = null,
            ICollection<KeyValuePair<string, string>> headers = null)
        {
            if (string.IsNullOrEmpty(strUrl))
            {
                throw new ArgumentNullException("url");
            }
            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (strUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(strUrl) as HttpWebRequest;
            }
            else if (strUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
            {
                request = WebRequest.Create(strUrl) as HttpWebRequest;
            }
            else
            {
                request = WebRequest.Create("http://" + strUrl) as HttpWebRequest;
            }
            request.KeepAlive = false;
            request.Method = strMethod;
            if (strReferer != null)
            {
                request.Referer = strReferer;
            }
            if (cookies != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(cookies);
            }
            if (intTimeoutMs.HasValue)
            {
                request.Timeout = intTimeoutMs.Value;
            }
            request.UserAgent = DefaultUserAgent;
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    request.Headers.Add(item.Key, item.Value);
                }
            }
            return request;
        }

        /// <summary>
        /// 设置验证密码
        /// </summary>
        /// <param name="request"></param>
        /// <param name="strUser"></param>
        /// <param name="strPwd"></param>
        public static void SetCredentials(HttpWebRequest request, string strUser, string strPwd)
        {
            request.Credentials = new NetworkCredential(strUser, strPwd);
        }

        /// <summary>
        /// 向HttpRequest Post数据
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>
        public static void PostData(HttpWebRequest request, byte[] buffer)
        {
            if (buffer != null && buffer.Length > 0)
            {
                request.ContentLength = buffer.Length;
                using (var stream = request.GetRequestStream())
                {
                    //设置POST 数据
                    stream.Write(buffer, 0, buffer.Length);
                    stream.Close();
                }
            }
        }

        /// <summary>
        /// 向HttpRequest Post数据
        /// </summary>
        /// <param name="request"></param>
        /// <param name="strData"></param>
        /// <param name="enc"></param>
        public static void PostData(HttpWebRequest request, string strData, Encoding enc = null)
        {
            if (enc == null)
            {
                enc = Encoding.UTF8;
            }
            byte[] buffer = enc.GetBytes(strData);
            PostData(request, buffer);
        }

        /// <summary>
        /// 从HttpWebResponse的ResponseStream中获取内容到文本
        /// </summary>
        /// <param name="request">response</param>
        /// <param name="intTimeOut">超时标记(毫秒)</param>
        /// <param name="encoding">encoding</param>
        /// <returns>返回值</returns>
        public static string SGetContext(
            HttpWebRequest request,
            int? intTimeOut = null,
            Encoding encoding = null)
        {
            var response = request.GetResponse() as HttpWebResponse;
            return SGetContext(response, intTimeOut, encoding);
        }

        /// <summary>
        /// 从HttpWebResponse的ResponseStream中获取内容到文本
        /// </summary>
        /// <param name="response">response</param>
        /// <param name="intTimeOut">超时标记(毫秒)</param>
        /// <param name="encoding">encoding</param>
        /// <returns>返回值</returns>
        public static string SGetContext(
            HttpWebResponse response,
            int? intTimeOut = null,
            Encoding encoding = null)
        {
            using (Stream receiveStream = response.GetResponseStream())
            {
                string strEncodeing = response.ContentEncoding;
                if (encoding == null)
                {
                    if (string.IsNullOrEmpty(strEncodeing))
                    {
                        //默认编码
                        strEncodeing = "UTF-8";
                    }
                    encoding = Encoding.GetEncoding(strEncodeing);
                }
                if (intTimeOut.HasValue)
                {
                    receiveStream.ReadTimeout = intTimeOut.Value;
                }
                string strResult = SGetContext(receiveStream, encoding);
                return strResult;
            }
        }

        /// <summary>
        /// 从流中读取文本
        /// </summary>
        /// <param name="stream">stream</param>
        /// <param name="encoding">encoding</param>
        /// <returns>返回值</returns>
        public static string SGetContext(Stream stream, Encoding encoding = null)
        {
            string strResult;
            if (encoding != null)
            {
                using (StreamReader sr = new StreamReader(stream, encoding))
                {
                    strResult = sr.ReadToEnd();
                }
            }
            else
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    strResult = sr.ReadToEnd();
                }
            }
            return strResult;
        }

        /// <summary>
        /// 有效性验证回调方法
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="certificate">certificate</param>
        /// <param name="chain">chain</param>
        /// <param name="errors">errors</param>
        /// <returns>返回值</returns>
        private static bool CheckValidationResult(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors errors)
        {
            //总是接受
            return true;
        }
    }
}